#ifndef SANDBOX_SDK_MATH_QUANTERNION4F_HPP
#define SANDBOX_SDK_MATH_QUANTERNION4F_HPP

#include "matrix4f.hpp"
#include <type_traits>

namespace sandbox
{
	namespace sdk
	{
		//==================================================================
		//quaternions
		//see http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
		struct Quaternion  {
			Quaternion(){}
			Quaternion(const Vector4f  axis){
				__m128 cos, sin;
				detail::sincos_ps(_mm_set1_ps(angle*0.5f), cos, sin);
				value=_mm_mul_ps(axis.norm().value,sin);
				value=_mm_move_ss(value,cos);
			}
			Quaternion norm()const
			{
				register __m128 mm1=_mm_mul_ps(value,value);
				mm1 = _mm_add_ps(mm1, 
					::sandbox::sdk::detail::shuffle<__m128,1,0,3,2>(mm1);
				mm1 = _mm_add_ps(mm1, 
					::sandbox::sdk::detail::shuffle<__m128,2,2,0,0>(mm1);
				mm1 = _mm_rsqrt_ps(mm1);
				mm1 = _mm_mul_ps(mm1, value);
				return Quaternion(mm1);
			}
			Quaternion(__m128 v):value(v){}
			__m128 value;
		};
		
	}
}
#endif //SANDBOX_SDK_MATH_QUATERNION4F_HPP
